#!/usr/bin/env python

import os
import sys
import pygame
from pygame import *
import math

DEBUG = 0

def readAmmoFile():
   # [(name,mass,windresit,xspeed,yspeed,xloc,yloc,termVol,gravity)]
   return [('potato',1,1,0,0,0,0,175,9.6),('egg',.5,.5,0,0,0,0,200,9.6),('tomato',.75,.75,0,0,0,0,100,9.6),('cow',3,1,0,0,0,0,200,9.6)]
   
class Field:
   players = []
   inFlightAmmo = []
   cur_player = 0
   lenght = 200 # in meters
   time_factor = 1
   
   def __init__(self, lenght_in = 200, localShft_in = 20):
      self.lenght = lenght_in
      self.players.append(Player(self,localShft_in,0,readAmmoFile(),45))
      self.players.append(Player(self,self.lenght - localShft_in,0,readAmmoFile(),135))
      
   def step(self,time_factor_in):
      for shot in self.inFlightAmmo:
         shot.step(time_factor_in)
         
   def getPlayer(self):
      return self.players[self.cur_player]
   
   def setNextPlayer(self):
      if self.cur_player +1 == len(self.players):
         self.cur_player = 0
      else:
         self.cur_player += 1

class Player:
   width = 20     # in meters
   height = 10    # in meters
   health = 100
   barrel_len = 0
   barrel_center = 0,0
   
   def __init__(self,field_in,xloc_in,yloc_in,ammolist_in,declination_in):
      self.position = (xloc_in,yloc_in)
      self.weapon = Weapon(self,ammolist_in,declination_in)
      self.field = field_in

   def getPosition(self):
      return self.position

   def getbarrelEnd(self):
      rad = self.weapon.getDeclination() * math.pi / 180
      self.xOffset = self.barrel_len * math.cos(rad)
      self.yOffset = self.barrel_len * math.sin(rad)
      return self.xOffset, self.yOffset

class Ammo:
   def __init__(self, name_in='blank',mass_in=4,windresit_in=0,xspeed_in=0,yspeed_in=0,xloc_in=400,yloc_in=500,termVol_in=20,gravity_in=9.6):
      self.name = name_in
      self.mass = mass_in
      self.windresit = windresit_in
      self.xspeed = xspeed_in
      self.yspeed = yspeed_in
      self.xloc = xloc_in
      self.yloc = yloc_in
      self.termVol = termVol_in
      self.gravity = gravity_in
      self.inflight = False

   def step(self, time_factor_in):
      self.setXloc(self.getXloc() + (self.getXspeed() * time_factor_in))
      self.setYloc(self.getYloc() + (self.getYspeed() * time_factor_in))
      self.setXspeed(self.getXspeed() - self.getWindResit()* time_factor_in)
      self.setYspeed(self.getYspeed() - self.getGravity()* time_factor_in)

   def applyForce(self, force, angle):
      speed = force/self.mass
      rad = math.radians(angle)
      self.setXspeed(speed*math.cos(rad))
      self.setYspeed(speed*math.sin(rad))

   def setName(self, name_in):
      self.name = name_in
      
   def setMass (self, mass_in):
      self.mass = mass_in
      
   def setWindResistance(self, wr_in):
      self.windresit = wr_in
      
   def setXspeed(self, xspeed_in):
      self.xspeed = xspeed_in
      if self.yloc <= 0:
         self.xspeed = 0
      if DEBUG: print "xspeed" + str(self.yspeed)
      
   def setYspeed(self, yspeed_in):
      self.yspeed = yspeed_in
      if self.yloc <= 0:
         self.yloc = 0
         self.yspeed = 0
      if DEBUG: print "yspeed" + str(self.yspeed)
      
   def setXloc(self, xloc_in):
      self.xloc = xloc_in
      
   def setYloc(self, Yloc_in):
      self.yloc = Yloc_in
      if self.yloc < 0:
         self.yloc = 0
         self.setYspeed(0)

   def getName (self):
      return self.name

   def getWindResit (self):
      return self.windresit

   def getXspeed (self):
      return self.xspeed
 
   def getYspeed (self):
      return self.yspeed

   def getXloc (self):
      return self.xloc

   def getYloc(self):
      return self.yloc
   
   def getGravity(self):
      return self.gravity
   
   def getTermVol(self):
      return self.termVol
      
class Weapon:
   MAXFUEL = 100
   MAXDECLINATION = 180
   MINDECLINATION = 0
   FUELINDEX = 1
   fuel_ammount = 50
   init_xvol = 0
   init_yvol = 0
   force = 0
   current_ammo = Ammo()
   ammoIndx = 0   
   
   def __init__(self, player_in, ammolst_in, declination_in):
      self.declination = declination_in
      self.ammolst = ammolst_in
      self.current_ammo = self.ammolst[self.ammoIndx]
      self.player = player_in
      
   def setFuel(self, fuel_in):
      self.fuel = self.fuel_in
   
   def setDeclination(self, declination_in):
      self.declination = declination_in
   
   def setForce(self):
      if DEBUG:
         print "force " + str(self.force)
      
   def getFuel (self):
      return self.fuel
   
   def getDeclination(self):
      return self.declination
   
   def getForce (self):
      return self.force
   
   def increaseFuel(self):
      if self.fuel_ammount < 100:
         self.fuel_ammount += 1
      else:
         self.fuel_ammount = 100
      if DEBUG:
         print "increase Fuel " + str(self.fuel_ammount)
   
   def decreaseFuel(self):
      if self.fuel_ammount > 0:
         self.fuel_ammount -= 1
      else:
         self.fuel_ammount = 0
      if DEBUG:
         print "increase Fuel " + str(self.fuel_ammount)
         
   def increaseDeclination(self):
      if self.declination < 180:
         self.declination += 1
      else:
         self.declination = 180
      if DEBUG:
         print "increase Declin " + str(self.declination)
   
   def decreaseDeclination(self):
      if self.declination > 0:
         self.declination -= 1
      else:
         self.declination = 0
      if DEBUG:
            print "decrease Declin " + str(self.declination)
            
            
   def nextAmmo(self):
      if self.ammoIndx + 1 == len(self.ammolst):
         self.ammoIndx = 0
      else:
         self.ammoIndx += 1
      self.current_ammo = self.ammolst[self.ammoIndx]
   
   def prevAmmo(self):
      if self.ammoIndx - 1 < 0 :
         self.ammoIndx = len(self.ammolst) -1
      else:
         self.ammoIndx -= 1
      self.current_ammo = self.ammolst[self.ammoIndx]
   
   def fire(self):
      fired_ammo = Ammo(*self.ammolst[self.ammoIndx])
      fired_ammo.setXloc(20)
      fired_ammo.setYloc(20)

      force = self.fuel_ammount * self.FUELINDEX
      fired_ammo.applyForce(force, self.declination)
      self.player.field.inFlightAmmo.append(fired_ammo)
      
      if DEBUG:
         print "len of ammoinflight " + str(len(self.player.field.inFlightAmmo))
